/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-  */
/*
 * tameshi
 * Copyright (C) 2012 Massimiliano Maniscalco <massi.neptune@gmail.com>
 * 
tameshi is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * tameshi is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "parser_xml.h"
#include <glibmm/convert.h>
#include <iostream>

#ifdef LIBXMLCPP_EXCEPTIONS_ENABLED
void ParserXML::
on_start_document()
{
	// start document
}

void ParserXML::
on_end_document()
{
	commit_import_end.emit();
}

void ParserXML::
on_start_element(const Glib::ustring& name, const AttributeList& attributes)
{
	if ( name == Glib::ustring ( "domanda" ) )
		quaestio->cleanup();
	if ( name == Glib::ustring ( "codex" ) )
		codice_elemento = 1; // codice
	if ( name == Glib::ustring ( "quaestio" ) )
		codice_elemento = 2; // domanda
	if ( name == Glib::ustring ( "responsio" ) )
	{
		codice_elemento = 3; // risposta
		indice++;
		if ( indice >= quaestio->numero_risposte () )
			indice = 0;
	}
	if ( name == Glib::ustring ( "diligens" ) )
		codice_elemento = 4; // corretta
	if ( name == Glib::ustring ( "argumentum" ) )
		codice_elemento = 5; // argomento
	if ( name == Glib::ustring ( "nota" ) )
		codice_elemento = 6; // appunti
	if ( name == Glib::ustring ( "responsiones" ) )
		codice_elemento = 7; // risposte
	if ( name == Glib::ustring ( "diligentes" ) )
		codice_elemento = 8; // corrette
	if ( name == Glib::ustring ( "extremus" ) )
		codice_elemento = 9; // ultima is corretta
	if ( name == Glib::ustring ( "tempus_summa" ) )
		codice_elemento = 10; // tempo totale
	if ( name == Glib::ustring ( "tempus_extremus" ) )
		codice_elemento = 11; // ultimo tempo
	if ( name == Glib::ustring ( "locutio" ) )
		tag_text_elem = 1; // stringa
	if ( name == Glib::ustring ( "tag_genus" ) )
		tag_text_elem = 2; // codice tag
	if ( name == Glib::ustring ( "locus" ) )
		tag_text_elem = 3; // posizione tag

	// Check attributes:
	for(xmlpp::SaxParser::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter)
	{
		cout << iter->name << endl;
	}
}

void ParserXML::
on_end_element(const Glib::ustring& name )
{
	if ( name == Glib::ustring ( "locutio" ) || name == Glib::ustring ( "tag_genus" ) || name == Glib::ustring ( "locus" ) )
		tag_text_elem = 0;
	else
	{
		if ( name == Glib::ustring ( "domanda" ) )
			commit_import_domanda.emit ( *quaestio );
		if ( name == Glib::ustring ( "tag" ) && tags->size() > 0 )
		{
			switch ( codice_elemento )
			{
				case 2: // domanda
					quaestio->set_tags_domanda ( *tags );
					break;
				case 3: // risposta
					quaestio->set_tags_risposta ( *tags, indice );
					break;
				case 6: // appunti
					quaestio->set_tags_appunti ( *tags );
					break;
			}
			tags->clear();
		}
		codice_elemento = 0;
	}
}

void ParserXML::
on_characters(const Glib::ustring& text)
{
	try
	{
		switch ( codice_elemento )
		{
			case 1: // codice
				quaestio->set_codice ( text );
				break;
			case 2: // domanda
				if ( tag_text_elem == 1 )
					quaestio->append_domanda ( text );
				if ( tag_text_elem == 2 || tag_text_elem == 3 )
					tags->push_back ( atoi ( text.c_str() ) );
				break;
			case 3: // risposta
				if ( tag_text_elem == 1 )
					quaestio->append_risposta ( text, indice );
				if ( tag_text_elem == 2 || tag_text_elem == 3 )
					tags->push_back ( atoi ( text.c_str() ) );
				break;
			case 4: // corretta
				quaestio->set_corretta ( atoi ( text.c_str() ) );
				break;
			case 5: // argomento
				cout << "argomento: " << text.raw() << endl;
				quaestio->set_argomento ( text );
				break;
			case 6: // appunti
				if ( tag_text_elem == 1 )
					quaestio->append_appunti ( text );
				if ( tag_text_elem == 2 || tag_text_elem == 3 )
					tags->push_back ( atoi ( text.c_str() ) );
				break;
			case 7: // risposte
				quaestio->set_risposte ( atoi ( text.c_str() ) );
				break;
			case 8: // corrette
				quaestio->set_corrette ( atoi ( text.c_str() ) );
				break;
			case 9: // ultima is corretta
				quaestio->set_ultima ( atoi ( text.c_str() ) );
				break;
			case 10: // tempo totale
				quaestio->set_tempo_totale ( parseTimeString ( text ) );
				break;
			case 11: // ultimo tempo
				quaestio->set_ultimo_tempo ( parseTimeString ( text ) );
				break;
		}
	}
	catch(const Glib::ConvertError& ex)
	{
		std::cerr << "ParserXML::on_characters(): Exception caught while converting text for std::cout: " << ex.what() << std::endl;
	}
}

void ParserXML::
on_comment(const Glib::ustring& text)
{
  try
  {
    std::cout << "on_comment(): " << text << std::endl;
  }
  catch(const Glib::ConvertError& ex)
  {
    std::cerr << "ParserXML::on_comment(): Exception caught while converting text for std::cout: " << ex.what() << std::endl;
  }
}

void ParserXML::
on_warning(const Glib::ustring& text)
{
  try
  {
    std::cout << "on_warning(): " << text << std::endl;
  }
  catch(const Glib::ConvertError& ex)
  {
    std::cerr << "ParserXML::on_warning(): Exception caught while converting text for std::cout: " << ex.what() << std::endl;
  }
}

void ParserXML::
on_error(const Glib::ustring& text)
{
  try
  {
    std::cout << "on_error(): " << text << std::endl;
  }
  catch(const Glib::ConvertError& ex)
  {
    std::cerr << "ParserXML::on_error(): Exception caught while converting text for std::cout: " << ex.what() << std::endl;
  }
}

void ParserXML::
on_fatal_error(const Glib::ustring& text)
{
  try
  {
    std::cout << "on_fatal_error(): " << text << std::endl;
  }
  catch(const Glib::ConvertError& ex)
  {
    std::cerr << "ParserXML::on_characters(): Exception caught while converting value for std::cout: " << ex.what() << std::endl;
  }
}

time_t ParserXML::
parseTimeString ( const Glib::ustring& str )
{
	time_t tempo;
	unsigned char i;
	int year, month, day, hour, minute, second;
	unsigned char pos;
	if ( str[0] == 'P' )
	{
		i = 1;
		while ( str[i] != 'Y' && i < str.size() )
			++i;
		year = atoi ( str.substr( 1, i - 1 ).c_str() );
		i++;
		pos = i;
		while ( str[i] != 'M' && i < str.size() )
			++i;
		month = atoi ( str.substr( pos, i - pos ).c_str() );
		i++;
		pos = i;
		while ( str[i] != 'D' && i < str.size() )
			++i;
		day = atoi ( str.substr( pos, i - pos ).c_str() );
		i += 2;
		pos = i;
		while ( str[i] != 'H' && i < str.size() )
			++i;
		hour = atoi ( str.substr( pos, i - pos ).c_str() );
		i++;
		pos = i;
		while ( str[i] != 'M' && i < str.size() )
			++i;
		minute = atoi ( str.substr( pos, i - pos ).c_str() );
		i++;
		pos = i;
		while ( str[i] != 'S' && i < str.size() )
			++i;
		second = atoi ( str.substr( pos, i - pos ).c_str() );
		tempo = second + ( minute * 60 ) + ( hour * 3600 ) + ( day * 86400 ) + ( month * 2592000 ) + ( year * 31536000 );
	}
	else
		cerr << "la stringa del tempo non inizia con P" << endl;
	return tempo;
}

#endif